package com.dkd.sbtz.mapper;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import com.dkd.common.core.domain.entity.SysDept;
import com.dkd.common.core.domain.entity.SysUser;
import com.dkd.sbtz.domain.AssetNodeRel;
import com.dkd.sbtz.domain.AssetNodeUsage;
import com.dkd.sbtz.domain.AssetWorkOrder;
import com.dkd.sbtz.domain.Sbtz;
import com.dkd.sbtz.domain.vo.*;
import com.dkd.sbtz.domain.vo.nodeImport.ParentLite;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

/**
 * 设备台账Mapper接口
 * 
 * @author xzj
 * @date 2025-09-02
 */
public interface SbtzMapper 
{
    /**
     * 查询设备台账
     * 
     * @param id 设备台账主键
     * @return 设备台账
     */
    public Sbtz selectSbtzById(Long id);

    /**
     * 查询设备台账列表
     * 
     * @param sbtz 设备台账
     * @return 设备台账集合
     */
    public List<Sbtz> selectSbtzList(Sbtz sbtz);





    /**
     * 新增设备台账
     * 
     * @param sbtz 设备台账
     * @return 结果
     */
    public int insertSbtz(Sbtz sbtz);

    /**
     * 修改设备台账
     * 
     * @param sbtz 设备台账
     * @return 结果
     */
    public int updateSbtz(Sbtz sbtz);

    /**
     * 删除设备台账
     * 
     * @param id 设备台账主键
     * @return 结果
     */
    public int deleteSbtzById(Long id);

    /**
     * 批量删除设备台账
     * 
     * @param ids 需要删除的数据主键集合
     * @return 结果
     */
    public int deleteSbtzByIds(Long[] ids);


    /*增加节点*/
    int insertNode(Sbtz node);
    int updatePath(@Param("id") Long id, @Param("path") String path);
    int existsCode(@Param("code") String code);
    Sbtz getById(@Param("id") Long id);
    int batchInsertRel(@Param("rels") List<AssetNodeRel> rels);
    int insertClosureForNewNode(@Param("parentId") Long parentId, @Param("newId") Long newId);

   /*修改所属相关*/
    int insertClosureForExistingNode(@Param("parentId") Long parentId,
                                     @Param("nodeId") Long nodeId);

    int updateSelfMetaAfterRehome(@Param("nodeId") Long nodeId,
                                  @Param("newParentId") Long newParentId,
                                  @Param("ancestors") String ancestors,
                                  @Param("path") String path,
                                  @Param("level") Integer level,
                                  @Param("operUser") String operUser);
    // SbtzMapper.java
    int deleteSelfExternalClosure(@Param("nodeId") Long nodeId);
    // SbtzMapper.java
    int deleteChildrenByAncestor(@Param("rootId") Long rootId);
    int deleteChildrenSpareLinks(@Param("rootId") Long rootId);





    int existsAncestor(@Param("ancestorId") Long ancestorId,
                      @Param("descendantId") Long descendantId);

    // 覆盖根节点字段（不含 parent_id）
    int updateRootFields(@Param("id") Long id,
                         @Param("nodeType") String nodeType,
                         @Param("name") String name,
                         @Param("code") String code,
                         @Param("remark") String remark,
                         @Param("operUser") String operUser);

    // 编码唯一性校验（排除自身）
    int countCodeExcludeSelf(@Param("code") String code, @Param("selfId") Long selfId);



    // 闭包与元数据
    int detachSubtreeExternal(@Param("rootId") Long rootId);
    int attachSubtreeExternal(@Param("rootId") Long rootId,
                              @Param("newParentId") Long newParentId);
    int updateSubtreeMeta(@Param("rootId") Long rootId,
                          @Param("oldPrefixPath") String oldPrefixPath,
                          @Param("newPrefixPath") String newPrefixPath,
                          @Param("oldAncPrefix") String oldAncPrefix,
                          @Param("newAncPrefix") String newAncPrefix,
                          @Param("baseLevel") int baseLevel,
                          @Param("operUser") String operUser);
    int updateParent(@Param("rootId") Long rootId,
                     @Param("newParentId") Long newParentId,
                     @Param("operUser") String operUser);
    /*修改所属相关完*/





    // 懒加载：取 parentId 的直接子节点（parentId=0 表示根）
//    List<Map<String, Object>> listChildren(@Param("parentId") Long parentId);
//    int countChildren(@Param("id") Long id);

    /*根据父ID 查找数据*/
    List<Sbtz> selectByParentId(@Param("parentId") Long parentId);

    // 判断是否有子节点，用于给前端标记 leaf
    int existsChild(@Param("id") Long id); // 返回 0/1：是否存在子节点


    Sbtz findOneByParentTypeCode(@Param("parentId") Long parentId,
                                 @Param("nodeType") String nodeType,
                                 @Param("code")     String code);

    /*修改节点所属操作*/
    /*查找闭包表asset_node_rel的id对应的子节点*/
    List<Long> selectDescendantIds(@Param("nodeId") Long nodeId);

    /*批量删除asset_node表的id*/
    int deleteNodesByIds(@Param("ids") List<Long> ids);

    /*删除asset_node表的单条id*/
    int deleteNodeById(@Param("id") Long id);


    /** A：直接用 asset_node.spare_id 取备件 */
    List<AssetNodeListVO> selectSbtzListVO(Sbtz param);

    List<AssetNodeListVO> selectSearchData(Sbtz q);

    // 行级锁（InnoDB）
    Sbtz lockById(@Param("id") Long id);

    /** 根据查询条件返回导出数据（含 fullPath） */
    List<AssetNodeExportVO> selectForExport(Sbtz q);

    List<ExportWithParentVO> selectChainRowsForExport(Sbtz sbtz);


    /*修改操作时 更新表数据*/
    int updateByIdSelective(SbtzPatchReq req);


    public List<Sbtz> selectAssetTreeList(Sbtz sbtz);


    /*忽略冲突插入 设备部门启用 停用 表*/
    AssetNodeUsage selectOpenByAsset(@Param("assetId") Long assetId);

    int closeOpenByAsset(@Param("assetId") Long assetId,
                         @Param("endTs") LocalDateTime endTs);

    int insertIgnore(AssetNodeUsage u);



    List<AssetNodeUsage> selectDeptUsageList(AssetNodeUsage nodeUsage);
    List<AssetNodeUsage> selectNodeUsageById(AssetNodeUsage q);


    public List<Sbtz> selectSbtzSpare(Sbtz sbtz);



    /** 设备分页（只查设备本身字段，不做 join） */
    List<Sbtz> selectNodePage(Sbtz sbtz);

    /** 批量取这批设备的备件行（asset_id + 备件字段） */
    List<NodeSpareRow> selectNodeSpares(@Param("assetIds") List<Long> assetIds);


    List<AssetWorkOrder.AssetNodeDTO> listByIds(@Param("ids") List<Long> ids);



    /**
     * 仅更新扩展 7~8 个字段（选择性）
     */
    int updateExtSelective(Sbtz entity);

    /**
     * 仅当数据库 specification 为空/空串时才更新（选择性）
     */
    int updateExtSelectiveWhenSpecEmpty(Sbtz entity);



    /*测试导入数据*/
    Long selectIdByNameAndParent(@Param("name") String name, @Param("parentId") Long parentId);

    int insertExcelNode(Sbtz n);

    int updatePathLevel(@Param("id") Long id,
                        @Param("ancestors") String ancestors,
                        @Param("path") String path,
                        @Param("level") Integer level);

    int updatePartFields(Sbtz n);

    Sbtz selectById(Long id);

    // 闭包表
    int insertRelSelf(@Param("id") Long id);

    int insertRelByParent(@Param("parentId") Long parentId, @Param("childId") Long childId);
    // 新的：一次性查出根层（parent_id=0）的父节点（系统）列表
    List<ParentLite> selectAllRootParents();

    // 可选：直接让 MyBatis 组装 Map<name,id>（要求 name 唯一；有重名会被覆盖，谨慎使用）
    @MapKey("name")
    Map<String, ParentLite> selectAllRootParentsAsMap();

    List<Sbtz> selectAllRootSystems();
    /*测试导入数据end*/


    AssetWorkOrder.AssetNodeDTO selectNodeById(@Param("id") Long id);


    Integer checkBeTypeFirst(@Param("params") Map<String, Object> params);
    Long selectMinIdByBeType(@Param("beType") String beType);
    int updateBeTypeFirst(@Param("id") Long id, @Param("flag") Integer flag);



    boolean existsByCode(String code);
    String getMaxCodeByType(String nodeType);

    Sbtz selectLastIdByName(String parentName);

    Sbtz selectRootInfo(String code);

}
